package com.fingersoft.feature.login

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import android.util.Log
import cn.fingersoft.util.BuildConfigUtil
import com.fingersoft.business.BusinessContext
import com.fingersoft.business.api.ApiUtils
import com.fingersoft.business.deviceverify.VerifyDeviceEntity
import com.fingersoft.common.ICallback
import com.fingersoft.feature.faceId.FaceIDExport.Companion.moduleSecInit
import com.fingersoft.feature.login.api.LoginData
import com.fingersoft.feature.newlock.LockManager.Companion.LOCK_TYPE_GESTURE
import com.fingersoft.feature.newlock.LockManager.Companion.instance
import com.fingersoft.feature.personal.PersonalContext
import com.fingersoft.feature.personal.api.UserDetailBean
import com.fingersoft.feature.userinfo.model.User
import com.fingersoft.im.api.UserAgent
import com.fingersoft.im.api.base.AbsCallbackWithDeviceCheck
import com.fingersoft.im.api.base.BaseModelCallback2
import com.fingersoft.im.model.TokenInfo
import com.fingersoft.im.ui.home.startMainActivity
import com.fingersoft.im.utils.AppUtils
import com.fingersoft.im.utils.JSONUtils
import com.fingersoft.im.utils.UserInfoManager.saveCurrentUserInfo
import com.fingersoft.util.DeviceHelper
import com.fingersoft.util.UserInfoHelper
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.HttpHeaders
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.Call
import okhttp3.Response
import java.lang.ref.WeakReference


class SealLoginContext2(application: Application) : SealLoginContext(application) {
    companion object {
        private const val TAG = "LoginContext"
    }

    init {
        BusinessContext.lockSkipActivityNameList.add(LoginActivity::class.java.name)
    }

    override fun gotoMainActivity(loginActivity: Activity) {
        GlobalScope.launch(Dispatchers.Main) {
            val b = BusinessContext.user?.validateUser()
            if (b == true) {
                if (BuildConfigUtil.getBoolean("appWidgetBack2Source", false)) {
                    back2Home(loginActivity)
                } else {
                    startMainActivity(loginActivity, 0, false)
                }
            } else {
                LoginActivity.start(loginActivity)
            }
            BusinessContext.mLocationProvider?.release()
            loginActivity.finish()
        }
    }

    override fun getSolidUserNameForLogin(contextReference: WeakReference<Context>): String? {
        val verifyEntity = BusinessContext.deviceVerify?.getDeviceVerification(contextReference)
        return if (BuildConfigUtil.getBoolean("useVerifyDevicePolicy", false)) {
            verifyEntity?.user_info?.username
        } else {
            null
        }
    }

    override fun getSolidUserForLogin(contextWeakReference: WeakReference<Context>?): VerifyDeviceEntity? {
        val verifyEntity = BusinessContext.deviceVerify?.getDeviceVerification(contextWeakReference!!)
        return if (BuildConfigUtil.getBoolean("useVerifyDevicePolicy", false)) {
            verifyEntity
        } else {
            null
        }
    }

    override fun saveCurrentUserInfo(activity: Activity?, data: LoginData) {
        val dataUserInfo = data.user!!
        val user = User().apply {
            userId = dataUserInfo.id
            userName = dataUserInfo.username
            realName = dataUserInfo.name
            password = dataUserInfo.password
            gender = dataUserInfo.gender
            empLivingPhoto = dataUserInfo.icon
            imid = dataUserInfo.imid
            gesturePassword = dataUserInfo.gesturePassword
            mobile = dataUserInfo.mobile
            apiTimeStamp = System.currentTimeMillis()
            jobNnumber = dataUserInfo.jobNumber
        }
        AppUtils.saveUser(user)
        val tokenInfo: TokenInfo = AppUtils.getTokenInfo()
        // tokenInfo.setAppPath(data.getAppPath());


        tokenInfo.did = data.deviceId
        tokenInfo.uid = user.userId
        val dataUserToken = data.usertoken
        tokenInfo.userToken = if (!TextUtils.isEmpty(dataUserToken)) dataUserToken else dataUserInfo.usertoken
        AppUtils.saveTokenInfo(tokenInfo)
        //登录后更新okgo的header


        val headers = HttpHeaders()
        headers.put("Content-Type", "application/json")
        val usertoken: String? = AppUtils.getTokenInfo().userToken
        headers.put("Emp-Info", JSONUtils.toJsonString(UserAgent(activity, usertoken, DeviceHelper.getDeviceID(activity))))
        OkGo.getInstance().addCommonHeaders(headers)
        instance.setPassword(LOCK_TYPE_GESTURE, AppUtils.getUser().gesturePassword ?: "")

        PersonalContext.instance.getUserDetail(activity, "i/user/userInfo", object : ICallback<UserDetailBean>(UserDetailBean::class.java) {
            override fun onSuccess(data: UserDetailBean) {
                saveCurrentUserInfo(UserInfoHelper.convertUserInfo(data, application))
                moduleSecInit()
            }

        })
    }

    private fun back2Home(activity: Activity?) {
        val home = Intent(Intent.ACTION_MAIN)
        home.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
        home.addCategory(Intent.CATEGORY_HOME)
        activity?.startActivity(home)
    }

    override fun post(activityWeakReference: WeakReference<Activity>, path: String?, json: String?, callback: ICallback<LoginData>?) {
        try {
            val activity = activityWeakReference.get()!!
            OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
                .upJson(json)
                .execute(object : BaseModelCallback2<LoginResponse2>(LoginResponse2::class.java) {
                    override fun onSuccess(loginResponse2: LoginResponse2?, call: Call, response: Response) {
                        /*避免403到super后被处理为kickedoff从而直接跳转到lock，因为登录页面login失败后不应该被处理为kickedoff*/
                        if (null != loginResponse2 && AbsCallbackWithDeviceCheck.KICK_OFF_LINE == loginResponse2.code) {
                            loginResponse2.code = loginResponse2.code + 1
                        }
                        super.onSuccess(loginResponse2, call, response)
                        if (ApiUtils.showApiSucceedErrorToast(loginResponse2, false)) {
                            callback?.onError()
                            return
                        }

                        val userId: String = loginResponse2?.data?.user?.id ?: ""
                        if (TextUtils.isEmpty(userId)) {
                            callback?.onSuccess(loginResponse2!!.data)
                            return
                        }
                        //hold activity, prevent it be release
                        val activityReference = WeakReference(activity)
                        val result = BusinessContext.Companion.deviceVerify?.verifyDevice2User(activityReference, userId, null) ?: true
                        if (result) {
                            callback?.onSuccess(loginResponse2!!.data)
                        } else {
                            callback?.onError()
                        }
                    }

                    override fun onError(call: Call, response: Response, e: Exception) {
                        super.onError(call, response, e)
                        AppUtils.showApiErrorToast()
                        callback?.onError()
                    }
                })
        } catch (e: Exception) {
            Log.e(TAG, "login error:${e.message}", e)
            AppUtils.showApiErrorToast()
            callback?.onError()
        }
    }
}
